//-----------------------------------------------------------------------------
//
// CodeXS - Copyright(c) Businessware Architects cc
// Contact: Willem J Fourie
// E-mail : willemf@bware.biz
//
// This file is part of CodeXS.
//
// CodeXS is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License (GPL) as 
// published by the Free Software Foundation version 2 of the License.
//
// CodeXS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with CodeXS; if not, write to:
//
// Free Software Foundation, Inc.
// 59 Temple Place
// Suite 330
// Boston
// MA  02111-1307  USA
//
//-----------------------------------------------------------------------------

using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using CodeXS.Application;
using CodeXS.Application.CommandLine;

namespace CodeXS.Application
{
	class ConsoleApp
	{
		private static string[] GetFilePaths(string FilePaths)
		{
			return FilePaths.Split(new char[]{',',';'});
		}
		private static string Name()
		{
			return
				"CodeXS  Console Application Version 0.57b 13 Jul 2006\r\n" + 
				"\tCopyright(c) 2004-2006 Businessware Architects CC\r\n";
		}
		private static string About()
		{
			return
				ConsoleApp.Name() + "\r\n" +
				"Usage:\r\n" + 
				"cxsc " + 
				"-xs=\"SchemaFilePath\" "  +
				"-ns=\"CodeNamespaceName\" " + 
				"[-out=\"OutputFolder\"]" +
				"[-lang=\"Lang\"]" + 
				"[-i={\"ImportSchemaFilePath\"},{..}]" +
				"[-m={\"ICodeModifierFilePath\"},{..}]" +
				"[/r][[/v]{|}[/s]][[/11]{1}[/20]][/h]\r\n\r\n" +
				"-xs=\"SchemaFilePath\"\t:\tSchema (XSD) file path\r\n"  +
				"-ns=\"CodeNamespaceName\"\t:\tCode namespace name\r\n" + 
				"-out=\"OutputFolder\"\t:\tCode file output folder\r\n" +
				"-lang=Lang]\t\t:\tCode language:CS=C#,VB=Visual Basic\r\n" + 
				"\t\t\t\tDefaultlanguage=C#\r\n" +
				"-i=\"ImportFilePath\"\t:\tImport schema(s) (XSD) file path(es)\r\n" +
				"-m=\"ModifierFilePath\"\t:\tICodeModifier assembly filepath(es)\r\n" +
				"/r\t\t\t:\tRaw mode - generates XSD tool raw output\r\n" +
				"/v\t\t\t:\tVerbose reporting mode (default mode)\r\n" +
				"/s\t\t\t:\tSilent mode (no reporting)\r\n" +
				"/h\t\t\t:\tDisplays this prompt\r\n" +
				"/11 : Generate for .NET Version 1.1.4322.xxx. (See notes below)\r\n" +
				"/20 : Generate for .NET Version 2.0.50727.xx. (See notes below)\r\n\r\n" +
				"[] terms are optional\r\n" +
				"{|} indicates one term or the other (not both)\r\n" +
				"{} terms can be repeated separated by commas for multiple items\r\n\r\n" +
				"Notes:\r\n" +
				" 1. Will execute using the required .NET version, if installed,\r\n" +
				"    else will execute on the latest installed .NET Version.\r\n" +
				" 2. CodeXS.Schema.StandardCodeModifier.{.NET Version string}.dll is\r\n" +
				"    included by default.\r\n\r\n" +
				" .NET version      .NET Version string\r\n" +
				" ------------      -------------------\r\n" +
				" 1.1.4322.xxx      Net1_1\r\n" +
				" 2.0.50727.xx      (null)\r\n\r\n" +
				"Running in .NET Version : " +	System.Environment.Version.ToString() + "\r\n";
		}
		static private string GetLogEntryPrefix()
		{
			return System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
		}
		static private void LogMessage(string Message)
		{
			Console.WriteLine("{0}: {1}", ConsoleApp.GetLogEntryPrefix(),
				Message);
		}
		static private string[,] langName = new string[,]
		{
			{ "CS", "Microsoft C#.NET" },
			{ "VB", "Microsoft Visual Basic.NET" },
		};
		static private string GetLanguage(string Provider)
		{
			for(int i = 0; i < langName.GetLength(0); i++)
			{
				if(langName[i,0] == Provider) return langName[i,1];
			}
			return langName[1,1];
		}
		[STAThread]
		static void Main(string[] args)
		{
            string tNameSpace = "";
			Arguments cmdArgs = new Arguments(args);
			if( (cmdArgs.Count > 0) &&
				(cmdArgs["h"] == null) )
			{
				string outFolder = cmdArgs["out"] as string;
				if (outFolder != null)
				{
					DirectoryInfo di = new DirectoryInfo(outFolder);
					outFolder = di.FullName;
				}
				string codeProvider = "CS";
				string lang = cmdArgs["lang"] as string;
				if(lang != null)
				{
					lang = lang.ToUpper();
					switch(lang)
					{
						case "CS":
						case "VB":
							break;
						default:
							lang = codeProvider;
							break;
					}
					codeProvider = lang;
				}
				CodeDomProvider codeDomProvider = null;
				switch(codeProvider)
				{
					case "CS":
					default:
						codeDomProvider = new CSharpCodeProvider();
						break;
					case "VB":
						codeDomProvider = new VBCodeProvider();
						break;
				}
				string[] imports = null;
				string i = cmdArgs["i"] as string;
				if(i != null)
				{
					imports = ConsoleApp.GetFilePaths(i);
				}
				// CHANGE: 2006-06-29:	  Version 0.57 Beta
				// ISchemaObjectreaders are removed.
				string[] modifiers = null;
				if (cmdArgs["r"] == null)
				{
					string m = cmdArgs["m"] as string;
					ArrayList mList = new ArrayList();
					if (m == null)
					{
						mList.Add(Generator.GetStandardModifierFileName());
					}
					else
					{
						modifiers = ConsoleApp.GetFilePaths(m);
						if(modifiers.Length > 0)
						{
							mList.AddRange(modifiers);
						}
					}
					modifiers = (string[])mList.ToArray(typeof(string));
				}
				bool verbose = (cmdArgs["v"] != null);
				bool silent = (cmdArgs["s"] != null);
				if( ! silent)
				{
					Console.Write(ConsoleApp.Name());
					Console.WriteLine(".NET Version : {0}", 
						System.Environment.Version.ToString());
					Console.WriteLine("Code language: {0}",
						ConsoleApp.GetLanguage(codeProvider));
					ConsoleApp.LogMessage("Starting generation..");
				}
				// CHANGE: 2006-06-29:	 Version 0.57 Beta
				// ISchemaObjectReader's are removed.
                tNameSpace = cmdArgs["ns"].ToString();
                if (tNameSpace == "")
                {
                    System.IO.FileInfo tF = new FileInfo(cmdArgs["xs"]);
                    tNameSpace = tF.Name.Substring(0, tF.Name.IndexOf("."));
                }

				Generator generator = new Generator(
					null,
					null,
					outFolder,
					tNameSpace,
					codeDomProvider,
					cmdArgs["xs"],
					imports,
					null,
					modifiers,
					true);
				if( ! silent)
				{
					string[] codeFilePaths = generator.CodeFilePaths;
					if( (codeFilePaths != null) &&
						(codeFilePaths.Length > 0) )
					{
						ConsoleApp.LogMessage("Generation completed.");
						Console.Write("Files generated:\r\n");
						for(int ip = 0; ip < codeFilePaths.Length; ip++)
						{
							Console.WriteLine("{0}. {1}", (ip + 1).ToString("###"),
								codeFilePaths[ip]);
						}
					}
				}
				if(verbose)
				{
					Console.WriteLine("Code generation report:\r\n");
					foreach (string w in generator.Warnings)
					{
						Console.WriteLine(w);
					}
				}
			}
			else
			{
				Console.Write(ConsoleApp.About());
			}
		}
	}
}
